﻿(function ($) {
    $.fn.enableField = function () {
        return this.each(function () {
            var $this = $(this);

            var disabledData = $this.data('disabled');
            if (!disabledData) {
                return;
            }
            $this.removeData('disabled');

            var state = $this.data('html-extensions-state');
            if (state) {
                $this.setState(state);
                $this.removeData('html-extensions-state');
            }

            if (!disabledData.wasDisabled) {
                $this.removeAttr('readonly');
                $this.removeAttr('disabled');
                $this.removeClass('disabled');

                $this.trigger('html-extensions-enabled');
            }
        });
    };
})(jQuery);

(function ($) {
    $.fn.disableField = function () {
        return this.each(function () {
            var $this = $(this);

            if ($this.data('disabled')) {
                return;
            }

            if ($this.is('input[type=hidden]')) {
                $this.val('');
                return;
            }

            $this.data('html-extensions-state', $this.getState());
            $this.resetState();

            if (!$this.attr("disabled")) {
                $this.data('disabled', { wasDisabled: false });

                if ($this.is('input:not([type=radio])') && $this.is('input:not([type=checkbox])')) {
                    $this.attr('readonly', 'readonly');
                    $this.addClass('disabled');
                }
                else {
                    $this.attr('disabled', 'disabled');
                    if ($this.is('select')) {
                        $this.addClass('disabled');
                    }
                }

                $this.trigger('html-extensions-disabled');
            } else {
                $this.data('disabled', { wasDisabled: true });
            }
        });
    };
})(jQuery);

(function ($) {
    $.fn.getState = function () {
        var $this = this;
        if ($this.is('input[type=checkbox]')) {
            return $this.is(':checked');
        } else if ($this.is('input[type=radio]')) {
            return $this.filter(':checked').val();
        } else if ($this.is('select')) {
            return { val: $this.val(), items: $this.children() };
        } else {
            return $this.val();
        }
    };
})(jQuery);

(function ($) {
    $.fn.setState = function (state) {
        var $this = this;
        if ($this.is('input[type=radio]') || $this.is('input[type=checkbox]')) {
            if (state) {
                $this.attr('checked', 'checked');
            } else {
                $this.removeAttr('checked', 'checked');
            }
        } else if ($this.is('select')) {
            $this.append(state.items);

            // Crazy hack to support IE6
            try {
                $this.val(state.val);
            }
            catch (ex) {
                setTimeout(function () {
                    $this.val(state.val);
                }, 1);
            }
        } else {
            $this.val(state);
        }
    };
})(jQuery);

(function ($) {
    $.fn.resetState = function () {
        var $this = this;
        if ($this.is('input[type=radio]') || $this.is('input[type=checkbox]')) {
            $this.removeAttr('checked', 'checked');
        } else if ($this.is('select')) {
            $this.empty();
        } else {
            $this.val('');
        }
    };
})(jQuery);

(function ($) {
    $.fn.getValue = function () {
        var $this = this;

        if ($this.size() > 1) {
            $this = $this.not('input[type=hidden]');
        }

        if ($this.is('input[type=checkbox]') || $this.is('input[type=radio]')) {
            if($this.size() > 1) {
                return $this.filter(':checked').val();
            } else {
                return $this.is(':checked');
            }
        } else {
            return $this.val();
        }
    };
})(jQuery);

function parseInt32(s) {
    return parseInt(s, 10);
}

function canParseInt(s) {
    if (s.trim().match('^-[0-9]+$|^[0-9]+$')) {
        return isFinite(parseInt(s, 10));
    }
    else {
        return false;
    }
}

function canParseDate(dateString) {
    var regex = '^(0[1-9]|[12][0-9]|3[01])[.](0[1-9]|1[012])[.](19|20)\\d\\d$';
    if (dateString.match(regex) != null) {
        var values = dateString.split('.');

        return isValidDate(values[2], values[1], values[0]);
    }

    return false;
}

function isValidDate(year, month, day){
    var date = new Date(year, month - 1, day);
    if (date != null) {
        if (date.getDate() == day && (date.getMonth() + 1) == month && date.getFullYear() == year) {
            return true;
        }
    }

    return false;
}

function parseDate(dateString) {
    if (canParseDate(dateString)) {
        var values = dateString.split('.')

        return new Date(values[2], values[1] - 1, values[0]);
    }

    return null;
}

function parseDay(dateString) {
    if (canParseDate(dateString)) {
        var date = parseDate(dateString);

        return date.getDate();
    }

    return null;
}

function parseMonth(dateString) {
    if (canParseDate(dateString)) {
        var date = parseDate(dateString);

        return date.getMonth() + 1;
    }

    return null;
}

function parseYear(dateString) {
    if (canParseDate(dateString)) {
        var date = parseDate(dateString);

        return date.getFullYear();
    }

    return null;
}

function parseEgnDate(egn) {
    var year = parseInt(egn.substring(0, 2), 10);
    var month = parseInt(egn.substring(2, 4), 10);
    var day = parseInt(egn.substring(4, 6), 10);

    if (month >= 21 && month <= 32) {
        month -= 20;
        year += 1800;
    }
    else if (month >= 41 && month <= 52) {
        month -= 40;
        year += 2000;
    }
    else {
        year += 1900;
    }

    if (isValidDate(year, month, day)) {
        return { year: year, month: month, day: day };
    }
    else {
        return null;
    }
}

function isNullOrEmpty(s) {
    return s == undefined || s == '';
}

function isNullOrWhiteSpace(s) {
    return s == undefined || s.trim() == '';
}

String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

function dateIsValid(d, m, y) {
    try {
        var x = new Date(d, m, y);
        return true;
    }
    catch (e) {
        return false;
    }
}

(function ($) {
    $.fn.changeVal = function (val) {
        var $this = this;
        if ($this.val() != val) {
            $this.val(val);
            $this.trigger('change');
        }
    };
})(jQuery);

(function ($) {
    $.createDescriptiveAutoComplete = function (url, textboxId, nameFieldId, idFieldId, descriptionFieldId, enableQuickSearch, additionalOptions) {

        // dots are replaced with underline in IDs
        textboxId = textboxId.replace('.', '_');
        if (nameFieldId)
            nameFieldId = nameFieldId.replace('.', '_');
        if (idFieldId)
            idFieldId = idFieldId.replace('.', '_');
        if (descriptionFieldId)
            descriptionFieldId = descriptionFieldId.replace('.', '_');        

        var $textbox = $('#' + textboxId);
        var $nameField = $('#' + nameFieldId);

        var $idField;
        if (idFieldId) {
            $idField = $('#' + idFieldId);
        }

        var extraParams = {};

        var $descriptionField;
        if (descriptionFieldId) {
            $descriptionField = $('#' + descriptionFieldId);
        }      

        var options = {
            dataType: 'json',
            parse: function (data) {
                var rows = new Array();
                for (var i = 0; i < data.length; i++) {
                    rows[i] = { data: data[i], value: data[i].Tag, result: data[i].Tag };
                }
                return rows;
            },
            formatItem: function (row, i, max) { return row.Tag; },
            extraParams: extraParams,
            traditional: true
        };

        $.extend(options, $.createDescriptiveAutoComplete.settings);

        if (additionalOptions) {
            $.extend(options, additionalOptions);
        }      

        $textbox.autocomplete(url, options).result(function (event, item) {
            $nameField.changeVal(item.Tag);
            if ($idField) {
                $idField.changeVal(item.Id);
            }
            if($descriptionField){
                $descriptionField.changeVal(item.Description);                            
            }
        });

        $textbox.blur(function () {
            if (!$('div.ac_results').is(':visible')) {
                if ($textbox.val() == '') {
                    $nameField.changeVal('');
                    if ($idField) {
                        $idField.changeVal('');
                    }
                    if($descriptionField){
                        $descriptionField.changeVal('');                            
                    }
                } else if (!enableQuickSearch) {
                    $textbox.changeVal($nameField.val());
                }
            }
        });

        if (enableQuickSearch) {
            // "QuickSearch" is a feature that does the following
            // if the user types something very fast and removes the focus from the field
            // we make a special search with the string the user entered and the limit parameter set to 0
            // if the backend returns a result we select it
            // the idea is that the user can quickly enter only the code for a field without waiting for the autocomplete to show suggestions
            $textbox.change(function () {
                if ($textbox.val() != '' && $textbox.val() != $nameField.val()) {
                    $.ajax({
                        async: false,
                        dataType: options.dataType,
                        url: url,
                        data: $.extend({
                            q: $textbox.val(),
                            limit: 0
                        }, extraParams),
                        success: function (data) {
                        //debugger;
                            if (data.length > 0) {
                                $nameField.changeVal(data[0].Tag);
                                if ($idField) {
                                    $idField.changeVal(data[0].Id);
                                }
                                if($descriptionField){
                                    $descriptionField.changeVal(data[0].Description);                            
                                }
                                $textbox.changeVal(data[0].Tag);
                            } else {
                                $textbox.changeVal($nameField.val());
                            }
                        },
                        error: function () {
                            $textbox.changeVal($nameField.val());
                        }
                    });
                }
            });
        }
    };

    $.createDescriptiveAutoCompleteSetup = function (settings) {
        $.extend($.createDescriptiveAutoComplete.settings, settings);
    };

    $.createDescriptiveAutoComplete.settings = {
        width: 100,
        highlight: false,
        multiple: false,
        max: 40,
        minChars: 1,
        delay: 1000
    };
})(jQuery);

(function ($) {
    $.createAutoComplete = function (url, textboxId, nameFieldId, idFieldId, parentFieldId, enableQuickSearch, additionalParentFieldIds, additionalOptions) {

        // dots are replaced with underline in IDs
        textboxId = textboxId.replace('.', '_');
        if (nameFieldId)
            nameFieldId = nameFieldId.replace('.', '_');
        if (idFieldId)
            idFieldId = idFieldId.replace('.', '_');
        if (parentFieldId)
            parentFieldId = parentFieldId.replace('.', '_');
        if (additionalParentFieldIds.length > 0) {            
            for (var i = 0; i < additionalParentFieldIds.length; i++) {
                additionalParentFieldIds[i] = additionalParentFieldIds[i].replace('.', '_');
            }                                     
        }

        var $textbox = $('#' + textboxId);
        var $nameField = $('#' + nameFieldId);

        var $idField;
        if (idFieldId) {
            $idField = $('#' + idFieldId);
        }

        var extraParams = {};

        if (parentFieldId) {
            $.extend(extraParams, { parentId: function () {
                return $('#' + parentFieldId).val();
            } 
            });
        }

        if (additionalParentFieldIds.length > 0) {
            $.extend(extraParams, { additionalParentIds: function () {
                var values = [];
                for (var i = 0; i < additionalParentFieldIds.length; i++) {
                    values.push($('#' + additionalParentFieldIds[i]).val());
                }
                return values;
            } 
            });
        }

        var options = {
            dataType: 'json',
            parse: function (data) {
                var rows = new Array();
                for (var i = 0; i < data.length; i++) {
                    rows[i] = { data: data[i], value: data[i].Tag, result: data[i].Tag };
                }
                return rows;
            },
            formatItem: function (row, i, max) { return row.Tag; },
            extraParams: extraParams,
            traditional: true
        };

        $.extend(options, $.createAutoComplete.settings);

        if (additionalOptions) {
            $.extend(options, additionalOptions);
        }

        $textbox.autocomplete(url, options).result(function (event, item) {
            $nameField.changeVal(item.Tag);
            if ($idField) {
                $idField.changeVal(item.Id);
            }            
        });

        $textbox.blur(function () {
            if (!$('div.ac_results').is(':visible')) {
                if ($textbox.val() == '') {
                    $nameField.changeVal('');
                    if ($idField) {
                        $idField.changeVal('');
                    }
                } else if (!enableQuickSearch) {
                    $textbox.changeVal($nameField.val());
                }
            }
        });

        if (enableQuickSearch) {
            // "QuickSearch" is a feature that does the following
            // if the user types something very fast and removes the focus from the field
            // we make a special search with the string the user entered and the limit parameter set to 0
            // if the backend returns a result we select it
            // the idea is that the user can quickly enter only the code for a field without waiting for the autocomplete to show suggestions
            $textbox.change(function () {
                if ($textbox.val() != '' && $textbox.val() != $nameField.val()) {
                    $.ajax({
                        async: false,
                        dataType: options.dataType,
                        url: url,
                        data: $.extend({
                            q: $textbox.val(),
                            limit: 0
                        }, extraParams),
                        success: function(data) {
                            if (data.length > 0) {
                                $nameField.changeVal(data[0].Tag);
                                if ($idField) {
                                    $idField.changeVal(data[0].Id);
                                }
                                $textbox.changeVal(data[0].Tag);
                            } else {
                                $textbox.changeVal($nameField.val());
                            }
                        },
                        error: function() {
                            $textbox.changeVal($nameField.val());
                        }
                    });
                }
            });
        }
    };

    $.createAutoCompleteSetup = function (settings) {
        $.extend($.createAutoComplete.settings, settings);
    };

    $.createAutoComplete.settings = {
        width: 400,
        highlight: false,
        multiple: false,
        max: 40,
        minChars: 1,
        delay: 1000
    };
})(jQuery);

(function ($) {
    $.createTreeView = function (url, textboxId, nameFieldId, idFieldId, parentFieldId, overlayId, overlayTargetId, treeViewId, createClearButton, additionalParentFieldIds, additionalOptions) {
        var $textbox = $('#' + textboxId);
        var $nameField = $('#' + nameFieldId);
        var $overlayDiv = $('#' + overlayId);
        var $overlayTarget = $('#' + overlayTargetId);
        var $treeDiv = $('#' + treeViewId);

        var disabled = $textbox.hasClass('disabled');

        var $idField;
        if (idFieldId) {
            $idField = $('#' + idFieldId);
        }

        var extraParams = {};

        if (parentFieldId) {
            $.extend(extraParams, { parentId: function () {
                return $('#' + parentFieldId).val();
            }
            });
        }

        if (additionalParentFieldIds.length > 0) {
            $.extend(extraParams, { additionalParentIds: function () {
                var values = [];
                for (var i = 0; i < additionalParentFieldIds.length; i++) {
                    values.push($('#' + additionalParentFieldIds[i]).val());
                }
                return values;
            }
            });
        }

        var options = $.extend({}, $.createTreeView.settings);

        if (additionalOptions) {
            $.extend(options, additionalOptions);
        }

        var $img;
        if (createClearButton) {
            $img = $('<input type="image" src="/Content/Images/clear.png" />').css({ position : 'absolute', display: 'none', margin: '0px' }).insertAfter($textbox);
            $img.load(function(){
                var pos = $textbox.offset();

                var topOffset = ($textbox.outerHeight() - $img.outerHeight()) / 2;
                var rightOffset = $img.outerWidth() + topOffset;

                pos.top += topOffset;
                pos.left += $textbox.outerWidth() - rightOffset;

                $img.css(pos);

                if($textbox.val() != '' && !disabled){
                    $img.show();
                }
            });

            $img.click(function(ev){
                ev.preventDefault();

                $textbox.changeVal('');
                $nameField.changeVal('');
                if($idField) {
                    $idField.changeVal('');
                }
                $img.hide();
            });
        }

        $overlayTarget.bind('html-extensions-disabled', function(){
            disabled = true;
            if ($img) {
                $img.hide();
            }
        });

        $overlayTarget.bind('html-extensions-enabled', function(){
            disabled = false;
            if ($img) {
                $img.show();
            }
        });

        $overlayTarget.overlay({
            top: 50,
            speed: 0,
            target: $overlayDiv,
            onClose: function(){
                $treeDiv.empty();
                $treeDiv.jstree("destroy");
            },
            onBeforeLoad: function(){
                if(disabled) {
                    return false;
                }
            },
            onLoad: function(){
                $textbox.blur();

                $overlayDiv.mask(options.loadingText);

                $.ajax({
                    url: url,
                    type: "GET",
                    dataType: 'json',
                    data: extraParams,
                    traditional: true,
                    success: function(result){
                        $overlayDiv.unmask("Waiting...");

                        $treeDiv
                            .jstree({ 
                                "plugins" : [ "json_data", "types", "themes", "ui" ],

                                core : {
                                     animation : 0
                                    //,"initially_open" : result.initially_open
                                },

                                "ui" : {
                                     "select_limit" : 1
                                    //,"initially_select" : result.initially_select
                                },

                                "json_data" : {
                                    "data" : result
                                },
                                "types" : {
                                    "types" : {
                                        "leaf" : {
                                            "icon" : {
                                                "image" : "/Content/Images/file.png"
                                            }
                                        },
                                        "node" : {
                                            "icon" : {
                                                "image" : "/Content/Images/folder.gif"
                                            },
                                            "hover_node" : false,
                                            "select_node" : function (e) {
                                                this.toggle_node(e);
                                                return false;
                                            }
                                        }
                                    }
                                },
                                "themes" : {  
                                    "url" : "/Content/Styles/jstree_theme/style.css"
                                }
                            });

                        if ($idField.val() != '') {
                            $('[data-id=' + $idField.val() + ']', $treeDiv).parentsUntil('div.treeview').filter('li[data-id]').each(function(){
                                $treeDiv.jstree("open_node", $(this));
                            });
                            $treeDiv.jstree("select_node", $('[data-id=' + $idField.val() + ']', $treeDiv));
                        }

                       $treeDiv.bind("select_node.jstree", function (event, data) {
                            $nameField.changeVal($.trim($(data.args[0]).text()));
                            if ($idField) {
                                $idField.changeVal($(data.args[0]).parent().attr('data-id'));
                            }

                            $textbox.changeVal($.trim($(data.args[0]).text()));

                            if ($img) {
                                $img.show();
                            }
                        });

                        $treeDiv.bind("dblclick.jstree", function (event) {
                            if($(event.target).closest("li").attr('rel') == 'leaf'){
                                $overlayTarget.overlay().close();
                            }
                        });
                    }
                });
            }
        });
    };

    $.createTreeViewSetup = function (settings) {
        $.extend($.createTreeView.settings, settings);
    };

    $.createTreeView.settings = {
        loadingText: 'Зареждане...'
    };
})(jQuery);

function disableButton(disableAfterClick, button) {
    if (disableAfterClick) {
        if (!$(button).data("clicked")) {
            $(button).data("clicked", true);

            if ($(button).is("input")) {
                $(button).attr("value", "Изчакайте...");
            }
            else {
                $(button).html('Изчакайте...');
            }

            return true;
        }
        else {
            return false;
        }
    }
    else {
        return true;
    }
}

(function ($) {
    $.submitPage = function (url, method, formId, confirmMessage, disableAfterClick, button) {
        if (confirmMessage && !confirm(confirmMessage))
            return;

        if (disableButton(disableAfterClick, button)) {
            doSubmit(url, method, formId);
        }
    };    

    function doSubmit(url, method, formId) {

        var strippedUrl = url;
        if (url.indexOf('?') >= 0) {
            strippedUrl = url.substring(0, url.indexOf('?'));
        }

        var form = $("<form style='display:none;' action='" + strippedUrl + "' method='" + method + "' />");

        // TODO: must copy the events from the original form to support javascript validation
        // form.copyEvents($('#' + formId)); //doesn't work

        // input elements of type 'file' and 'password' must be swapped with the cloned ones
        // because IE doesn't clone their values
        var hasSwappedInputs = false;
        var swapInputs = function () {
            var fileInputs = $('#' + formId + ' input').filter('[type=file], [type=password]');

            //swap the cloned inputs with the original ones since IE doesn't clone the value
            fileInputs.each(function () {
                var newFile = form.children('[name=' + $(this).attr('name') + ']');

                $(this).replaceWith(newFile).appendTo(form);
            });
        }

        if (formId) {

            // copy the elements by hand because we must preserve the order
            // but also have to handle some special cases
            $('#' + formId + ' *')
                .filter('input, select, textarea')
                .not('[type=submit], [type=button], [type=image]')
                .each(function () {
                    var newElement = $(this).clone();

                    // clone doesn't copy the selected and checked attributes
                    // of select, input[type=checkbox] and input[type=radio] elements
                    // so we do it by hand
                    if ($(this).is('select') || $(this).is('input[type=text]') || $(this).is('textarea')) {
                        newElement.val($(this).val());
                    } else if ($(this).is('input[type=checkbox], input[type=radio]')) {
                        newElement.attr('checked', $(this).attr('checked'));
                    }

                    newElement.appendTo(form);
                });

            // if we have file input elements set the 'enctype' attribute to 'multipart/form-data'
            if ($('#' + formId + ' input[type=file]').size() > 0) {
                form.attr('enctype', 'multipart/form-data');

                //IE requires that the encoding attribute is also set for dynamic forms
                if ($.browser.msie) {
                    form.attr('encoding', 'multipart/form-data');
                }
            }

            if ($.browser.msie) {
                hasSwappedInputs = true;

                swapInputs();
            }
        }

        if (url.indexOf('?') >= 0) {
            var qs = url.substring(url.indexOf('?') + 1, url.length);

            var queryString = $.parseQueryString(qs);

            for (var qsName in queryString) {
                qsValue = queryString[qsName];

                var input = $("<input type='text' name='" + qsName + "' value='" + qsValue + "' />");

                input.appendTo(form);
            }
        }

        form.appendTo('body').submit();

        // if we swapped input elements swap them back
        if (hasSwappedInputs) {
            swapInputs();
        }
    }
})(jQuery);

(function ($) {
    $.parseQueryString = function (qs) {
        if (qs == null)
            qs = location.search.substring(1, location.search.length);

        qs = qs.replace(/\+/g, ' ');

        var params = {};
        $.each(qs.split('&'), function (i, p) {
            p = p.split('=');
            p[0] = decodeURIComponent(p[0]);
            p[1] = decodeURIComponent(p[1]);
            params[p[0]] = p[1];
        });

        return params;
    }
})(jQuery);

var placeholder;
function showHelp(helpUrl, helpName) {
    var createDialog = function () {
        placeholder.dialog({
            title: 'Помощ',
            width: 810,
            height: 440,
            close: function () {
                $(this).empty();
                $(this).dialog('destroy');
            }
        });
        if ($('a[name=' + helpName + ']').size() > 0) {
            $('a[name=' + helpName + ']')[0].scrollIntoView(true);
        } else {
            placeholder.scrollTop(0);
        }
    }

    if (!placeholder) {
        placeholder = $('<div style="overflow: scroll;" />').hide();
        placeholder.load(helpUrl, '', createDialog);
    }
    else {
        createDialog();
    }
}

(function($) {
    $.formDialog = function(options) {
        var opts = $.extend({}, $.formDialog.settings, options);

        var placeHolder = $('<div/>')[0];

        if (opts.content) {
            $(placeHolder).html(opts.content);
        }

        var createDialogFunction = function() {
            var buttons = {};

            if (!opts.hideOkButton) {
                buttons[opts.okButtonText] = function() {
                    opts.okButtonFunction(placeHolder, opts);
                };
            }
            buttons[opts.cancelButtonText] = function() {
                opts.cancelButtonFunction(placeHolder, opts);
            };

            $(placeHolder).dialog({
                modal: opts.modal,
                width: opts.width,
                title: opts.title,
                close: opts.close,
                buttons: buttons
            });

            // handle ENTER to call OK button or cancel button in case OK button is hidden
            $(placeHolder).keypress(function(e) {
                if (((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) && !$(e.srcElement).is('textarea') && !$(e.target).is('textarea')) {
                    if (!opts.hideOkButton) {
                        opts.okButtonFunction(placeHolder, opts);
                    } else {
                        opts.cancelButtonFunction(placeHolder, opts);
                    }
                    return false;
                } else {
                    return true;
                }
            });
        };

        if (opts.contentUrl) {
            $(placeHolder).load(opts.contentUrl, '', function() {
                opts.dialogCreating(placeHolder);
                createDialogFunction();
                opts.dialogCreated(placeHolder);
            });
        }
        else {
            createDialogFunction();
        }
    };

    $.formDialogSetup = function(settings) {
        $.extend($.formDialog.settings, settings);
    };

    $.formDialog.settings = {
        cancelButtonFunction: cancelButtonFunction,
        cancelButtonText: 'Отказ',
        close: function() {
            $(this).empty();
            $(this).dialog('destroy');
        },
        dialogCreating: function() {
        },
        dialogCreated: function() {
        },
        error: function() {
        },
        hideOkButton: false,
        modal: true,
        okButtonFunction: okButtonFunction,
        serialForm: false,
        succeeding: function() {
        },
        success: function() {
        },
        okButtonText: 'Запис',
        type: 'POST',
        width: 450
    };

    function okButtonFunction(placeHolder, options) {
        var forms = $('form', placeHolder);

        var form;
        if (forms.size() == 1) {
            form = forms[0];
        }
        else if (forms.size() > 1) {
            throw new Error("There must be at most one form in the dialog");
        }

        var ajaxOptions = {
            type: options.type,
            url: options.actionUrl,
            dataType: 'json',
            error: options.error
        };

        if (form) {
            $.extend(ajaxOptions, {
                data: $(form).serializeArray(),
                success: function(formDialogResult) {
                    clearErrorsAndSummary(form);

                    if (formDialogResult.result == 'success') {
                        if (options.succeeding(placeHolder) != false) {
                            options.success();
                            $(placeHolder).empty();
                            $(placeHolder).dialog('destroy');
                        }
                    }
                    else if (formDialogResult.result == 'error') {
                        showErrors(form, formDialogResult.fieldErrors);
                        showSummary(form, formDialogResult.summaryErrors);
                    }
                    else if (formDialogResult.result == 'redirect') {
                        $(placeHolder).empty();
                        $(placeHolder).dialog('destroy');
                        $.redirect(formDialogResult.url);
                    }
                    else if (formDialogResult.result == 'loadNew') {
                        var newDialogOptions = $.extend({}, options, formDialogResult.options);

                        if (options.serialForm) {
                            $.extend(newDialogOptions, {
                                succeeding: function(newDialogPlaceHolder) {
                                    $.formDialog($.extend({}, options, {
                                        dialogCreating: function() {
                                            $(newDialogPlaceHolder).empty();
                                            $(newDialogPlaceHolder).dialog('destroy');
                                        }
                                    }));

                                    return false;
                                }
                            });
                        }

                        $.extend(newDialogOptions, {
                            dialogCreating: function() {
                                $(placeHolder).empty();
                                $(placeHolder).dialog('destroy');
                            }
                        });

                        $.formDialog(newDialogOptions);
                    }
                    else {
                        throw new Error("Unknown form dialog result");
                    }
                }
            });
        }
        else {
            $.extend(ajaxOptions, {
                data:{},
                success: function(result) {
                    options.success();

                    if (result.result == 'redirect') {
                        $.redirect(result.url);
                    }

                    $(placeHolder).empty();
                    $(placeHolder).dialog('destroy');
                }
            });
        }

        $.ajax(ajaxOptions);
    };

    function cancelButtonFunction(placeHolder, options) {
        $(placeHolder).dialog('close');
    };

    function showErrors(form, errors) {
        var formElements =
            $([])
            .add(form.elements)
            .filter(':input')
            .not(':submit, :reset, :image, [disabled]')
            .each(function() {
                var currentElement = this;

                var error = errors[$(currentElement).attr('name')];

                if (error) {
                    $('label[for=' + $(currentElement).attr('name') + ']', form).addClass('input-validation-error');
                }
            });
    };

    function showSummary(form, errors) {
        var ul =
            $('<ul/>')
            .attr({ 'generatedError': true })
            .addClass('error');

        for (var i = 0; i < errors.length; i++) {
            ul.append('<li>' + errors[i] + '</li>');
        }

        var $div = $('<div />')
            .attr({ 'generatedError': true })
            .addClass('validation-summary-errors');

        ul.appendTo($div);
        $div.appendTo(form);
    };

    function clearErrorsAndSummary(form) {
        $('label', form).removeClass('input-validation-error');
        $('[generatedError]', form).replaceWith('');
    };
})(jQuery);

(function($) {
    $.reloadPage = function() {
        location.reload();
    };
})(jQuery);

(function ($) {
    $.fn.reload = function (options) {
        return this.each(function () {
            var element = this;

            var url = $(document).attr('location').href;

            if (url.indexOf('#') >= 0) {
                url = url.substring(0, url.indexOf('#'));
            }

            $.ajax({
                url: url,
                type: "GET",
                dataType: "html",
                complete: function (res, status) {
                    // If successful, inject the HTML into all the matched elements
                    if (status == "success" || status == "notmodified") {
                        var selector = "#" + element.id;

                        var resp = res.responseText; //.replace(/<script(.|\s)*?\/script>/g, "");

                        var bodyOpeningTag = /<body>/i;
                        var bodyClosingTag = /<\/body>/i;
                        var match = bodyOpeningTag.exec(resp);
                        if (match) {
                            resp = resp.substring(match.index + match[0].length);

                            match = bodyClosingTag.exec(resp);
                            resp = resp.substring(0, match.index);
                        }

                        var newContent = $(resp).find(selector)[0].innerHTML;

                        $(element).html(newContent);
                    }
                }
            });
        });
    };
})(jQuery);

(function ($) {
    $.fn.exclusiveCheckbox = function (maxChoices) {
        if(!maxChoices){
            maxChoices = 1;
        }

        return this.each(function () {
            $(this).change(function () {
                var clicked = this;
                var skipN = maxChoices - 1;

                if ($(clicked).attr('checked')) {
                    $('[name=' + $(clicked).attr('name') + ']').each(function () {
                        if (this != clicked && $(this).attr('checked')) {
                            if(skipN > 0) {
                                skipN--;
                            }
                            else {
                                $(this).removeAttr('checked');
                            }
                        }
                    });
                }
            });
        });
    };
})(jQuery);

(function ($) {
    // mark the field as unfocusable to be skipped by the enterToTab extension
    // if the field is focused for any reason we unmark it as it is no longer considered unfocusable
    $.fn.autoGenerated = function () {
        return this.each(function () {
            $(this).addClass('unfocusable');

            $(this).focus(function () {
                $(this).removeClass('unfocusable');
            });
        });
    };
})(jQuery);

(function ($) {
    // mark the field as disabled and unfocusable to be skipped by the enterToTab extension
    $.fn.disableEdit = function () {
        return this.each(function () {
            $(this).addClass('disabled unfocusable').attr('readonly', 'readonly');
        });
    };

    // mark the field as enabled and focusable by the enterToTab extension
    $.fn.enableEdit = function () {
        return this.each(function () {
            $(this).removeClass('disabled unfocusable').removeAttr('readonly');
        });
    };
})(jQuery);

(function ($) {
    // pad the masked number fields with zeroes on the lefi
    // Example: for a 3 digit field: 5 -> 005
    $.fn.numberMasked = function () {
        return this.each(function () {
            var $this = $(this);
            $this.change(function(){
                if ($this.attr('maxlength') && $this.val().length < $this.attr('maxlength') && canParseInt($this.val())) {
                    var requiredPaddingLength = $this.attr('maxlength') - $this.val().length;
                    var padding = (new Array(requiredPaddingLength + 1)).join("0");
                    $this.val(padding + $this.val());
                }
            });
        });
    };
})(jQuery);

(function($) {
    var $originalFocusFields;
    var opts;

    $.enterToTab = function(options) {
        opts = $.extend({}, $.enterToTab.settings, options);

        $originalFocusFields = $('input, select, button, textarea').not('[readonly]').not('[disabled]').not(':hidden').not('[type=image]').add(".focusable");

        var $focusableFields = calculateTabIndexAttributes();

        $originalFocusFields.keypress(function (ev) {
            if (ev.keyCode == 13 && $(this).is(':not([type=submit], [type=button])')) {

                focusNextField($(this));

                return false;
            }
        });

        $originalFocusFields.keyup(function (ev) {
            var $this = $(this);
            if ((48 <= ev.keyCode && ev.keyCode <= 57) || (96 <= ev.keyCode && ev.keyCode <= 105)) { //digit 0-9
                if ($this.attr('maxlength') > 0 && $this.val().length == $this.attr('maxlength')) {
                    focusNextField($this);
                }
            }
        });

        if(opts.dontFocusFirstField) {
            return;
        }

        if ($focusableFields.size() > 0 && $($focusableFields[0]).is(':not([type=submit], [type=button])')) {
            $($focusableFields[0]).focus();
            $($focusableFields[0]).select();
            //opts.onfocus.apply($($focusableFields[0]));
        }
    };

    $.enterToTab.settings = {
        dontFocusFirstField: false,
        onfocus: function(){
        }
    };

    $.enterToTab.calculateTabIndexAttributes = function() {
        calculateTabIndexAttributes();
    };

    $.enterToTab.remove = function() {
        $originalFocusFields.removeAttr('tabindex');
        $originalFocusFields.unbind('keypress');
        $originalFocusFields = null;
    }

    function focusNextField($this) {
        $this.trigger('change');

        var nextTabIndex = parseInt($this.attr('tabIndex'), 10) + 1;

        var $nextEl = $('[tabIndex=' + nextTabIndex + ']');

        if ($nextEl.size() != 0) {
            $nextEl.focus();
            $nextEl.select();
            opts.onfocus.apply($nextEl);
        }
        else {
            var $firstEl = $('[tabIndex=1]');
            $firstEl.focus();
            $firstEl.select();
            opts.onfocus.apply($firstEl);
        }
    }

    function calculateTabIndexAttributes() {
        $originalFocusFields.filter('[readonly], [class~="disabled"], [disabled], .unfocusable').attr('tabIndex', -1);

        var $focusableFields = $originalFocusFields.not('[readonly]').not('[class~="disabled"]').not('[disabled]').not('.unfocusable').add(".focusable");
        $focusableFields.each(function (index) {
            $(this).attr('tabindex', index + 1);
        });

        return $focusableFields;
    }
})(jQuery);


(function ($) {
    var converter = {
        vertical: { x: false, y: true },
        horizontal: { x: true, y: false },
        both: { x: true, y: true },
        x: { x: true, y: false },
        y: { x: false, y: true }
    };

    var settings = {
        duration: "fast",
        direction: "both"
    };

    $.fn.extend({
        scrollintoview: function (options) {
            /// <summary>Scrolls the first element in the set into view by scrolling its closest scrollable parent.</summary>
            /// <param name="options" type="Object">Additional options that can configure scrolling:
            ///        duration (default: "fast") - jQuery animation speed (can be a duration string or number of milliseconds)
            ///        direction (default: "both") - select possible scrollings ("vertical" or "y", "horizontal" or "x", "both")
            /// </param>
            /// <return type="jQuery">Returns the same jQuery set that this function was run on.</return>

            options = $.extend({}, settings, options);
            options.direction = converter[typeof (options.direction) === "string" && options.direction.toLowerCase()] || converter.both;

            var dirStr = "";
            if (options.direction.x === true) dirStr = "horizontal";
            if (options.direction.y === true) dirStr = dirStr ? "both" : "vertical";

            var el = this.eq(0);
            var scroller = $('html');

            // check if there's anything to scroll in the first place
            if (scroller.length > 0 && el.size() > 0) {
                scroller = scroller.eq(0);
                var sizes = {
                    visible: (function () {
                        var vDim = scroller.offset();
                        return {
                            top: vDim.top,
                            left: vDim.left,
                            bottom: vDim.top + scroller[0].clientHeight,
                            right: vDim.left + scroller[0].clientWidth,
                            scrollX: scroller.scrollLeft(),
                            scrollY: scroller.scrollTop()
                        };
                    })(),
                    actual: (function () {
                        var vDim = el.offset();
                        return {
                            top: vDim.top,
                            left: vDim.left,
                            bottom: vDim.top + el.outerHeight(),
                            right: vDim.left + el.outerWidth()
                        };
                    })()
                };
                var padding = {
                    top: sizes.actual.top - sizes.visible.top,
                    bottom: sizes.visible.bottom - sizes.actual.bottom,
                    left: sizes.actual.left - sizes.visible.left,
                    right: sizes.visible.right - sizes.actual.right
                };

                var animOptions = {};

                // vertical scroll
                if (options.direction.y === true) {
                    if (padding.top < 0) {
                        animOptions.scrollTop = sizes.visible.scrollY + padding.top;
                    }
                    if (padding.top > 0 && padding.bottom < 0) {
                        // Using Math.Min() ensures that elements higher than scroll height get cut off at the bottom
                        animOptions.scrollTop = sizes.visible.scrollY + Math.min(-padding.bottom, padding.top);
                    }
                }

                // horizontal scroll
                if (options.direction.x === true) {
                    if (padding.left < 0) {
                        animOptions.scrollLeft = sizes.visible.scrollX + padding.left;
                    }
                    if (padding.left > 0 && padding.right < 0) {
                        // Using Math.Min() ensures that elements wider than scroll width get cut off on the right
                        animOptions.scrollLeft = sizes.visible.scrollX + Math.min(-padding.right, padding.left);
                    }
                }

                // scroll if needed
                if (!jQuery.isEmptyObject(animOptions)) {
                    scroller.animate(animOptions, options.duration);
                }
            }

            // return set back
            return this;
        }
    });
})(jQuery);

function bindField(sourceField, targetField) {
    var $source = $('#' + sourceField);
    var $target = $('#' + targetField);

    $source.change(function () {
        var $this = $(this);
        var val = $this.val();
        if (val != '' && val != undefined) {
            $target.val($this.find("option:selected").text());
        }
        else {
            $target.val('');
        }

        if ($this.attr("disabled")) {
            if (!$target.attr("disabled")) {
                $target.attr("disabled", "disabled");
            }
        }
        else {
            $target.removeAttr("disabled");
        }
    });
}

function createCascadingDropDown(codeFieldId, nameFieldId, parentFieldId, url, options) {
    var $select = $('#' + codeFieldId);
    var $nameField = $('#' + nameFieldId);
    var $parent = $('#' + parentFieldId);

    $select.CascadingDropDown($parent, url, options);

    bindField(codeFieldId, nameFieldId);
}

function createSimpleCascadingDropDown(childFieldId, parentFieldId, url, options) {
    var $select = $('#' + childFieldId);    
    var $parent = $('#' + parentFieldId);

    $select.CascadingDropDown($parent, url, options);    
}

(function ($) {
    $.fn.jqprint = function (options) {
        var opt = $.extend({}, $.fn.jqprint.defaults, options);

        var $element = (this instanceof jQuery) ? this : $(this);

        if (opt.operaSupport && $.browser.opera) {
            var tab = window.open("", "jqPrint-preview");
            tab.document.open();

            var doc = tab.document;
        }
        else {
            var $iframe = $("<iframe  />");

            if (!opt.debug) { $iframe.css({ position: "absolute", width: "0px", height: "0px", left: "-600px", top: "-600px" }); }

            $iframe.appendTo("body");
            var doc = $iframe[0].contentWindow.document;
        }

        if (opt.importCSS) {
            if ($("link[media=print]").length > 0) {
                $("link[media=print]").each(function () {
                    doc.write("<link type='text/css' rel='stylesheet' href='" + $(this).attr("href") + "' media='print' />");
                });
            }
            else {
                $("link").each(function () {
                    doc.write("<link type='text/css' rel='stylesheet' href='" + $(this).attr("href") + "' />");
                });
            }
        }

        if (opt.printContainer) { doc.write($element.outer()); }
        else { $element.each(function () { doc.write($(this).html()); }); }

        doc.close();

        (opt.operaSupport && $.browser.opera ? tab : $iframe[0].contentWindow).focus();
        setTimeout(function () { (opt.operaSupport && $.browser.opera ? tab : $iframe[0].contentWindow).print(); if (tab) { tab.close(); } }, 1000);
    }

    $.fn.jqprint.defaults = {
        debug: false,
        importCSS: true,
        printContainer: true,
        operaSupport: true
    };

    // Thanks to 9__, found at http://users.livejournal.com/9__/380664.html
    jQuery.fn.outer = function () {
        return $($('<div></div>').html(this.clone())).html();
    }

    $.fn.assignEnterKey = function (options) {
        var defaults =
            {
                triggerExp: ":input",
                targetExp: ":submit,:button"
            };
        var opts = $.extend(defaults, options);
        $(document).keypress(function (e) {
            if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
                $(".EnterKeyAssigned").find(opts.targetExp).click();
                return false;
            }
        });
        return this.each(function () {
            var obj = $(this); obj.find(opts.triggerExp).click(function () {
                obj.addClass("EnterKeyAssigned");
            }
            ).blur(function () {
                obj.removeClass("EnterKeyAssigned");
            });
        });
    };
})(jQuery);

function print(container) {
    $("#" + container).jqprint();
    return false;
}